<?php
/**
 * Date: 2024.8
 * Author: kahn
 * aliyun发送短信类库
 */

namespace sms\aliyun;

/**
 * 阿里短信通道
 * 参考：https://help.aliyun.com/product/44282.html?spm=5176.sms-template.102.8.29a01cbefjaicZ
 * @author zy
 */
class SmsManager {

    /*
     * 发送短信
     */
    public static function sendMsg($mobile, $reqData, &$resData){
        $config = \Yaf_Registry::get("config")->sms->aliyun->toArray();

        $params['PhoneNumbers'] = $mobile;
        $params['SignName'] = $config['smsSignName'];
        $params['TemplateCode'] = $config['code'];
        $params['TemplateParam'] = json_encode($reqData, JSON_UNESCAPED_UNICODE);

        $resData = self::request(
            $config['accessKeyId'],
            $config['accessKeySecret'],
            $config['domain'],
            array_merge($params, array(
                "RegionId" => "cn-hangzhou",
                "Action" => "SendSms",
                "Version" => "2017-05-25",
            ))
        );

        return $resData->Code == 'OK';
    }

    /**
     * 生成签名并发起请求
     *
     * @param $accessKeyId string AccessKeyId (https://ak-console.aliyun.com/)
     * @param $accessKeySecret string AccessKeySecret
     * @param $domain string API接口所在域名
     * @param $params array API具体参数
     * @param $security boolean 使用https
     * @return bool|\stdClass 返回API接口调用结果，当发生错误时返回false
     */
    public static function request($accessKeyId, $accessKeySecret, $domain, $params, $security=true) {
        $apiParams = array_merge(array (
            "SignatureMethod" => "HMAC-SHA1",
            "SignatureNonce" => uniqid(mt_rand(0,0xffff), true),
            "SignatureVersion" => "1.0",
            "AccessKeyId" => $accessKeyId,
            "Timestamp" => gmdate("Y-m-d\TH:i:s\Z"),
            "Format" => "JSON",
        ), $params);
        ksort($apiParams);
        $sortedQueryStringTmp = '';
        foreach ($apiParams as $key => $value) {
            $sortedQueryStringTmp .= "&" . self::encode($key) . "=" . self::encode($value);
        }

        $stringToSign = "GET&%2F&" . self::encode(substr($sortedQueryStringTmp, 1));

        $sign = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret . "&",true));

        $signature = self::encode($sign);

        $url = ($security ? 'https' : 'http')."://{$domain}/?Signature={$signature}{$sortedQueryStringTmp}";

        try {
            $content = httpGet($url);
            return json_decode($content);
        } catch( \Exception $e) {
            return false;
        }
    }

    private static function encode($str)
    {
        if( empty($str) ){
            return '';
        }
        $res = urlencode($str);
        $res = preg_replace("/\+/", "%20", $res);
        $res = preg_replace("/\*/", "%2A", $res);
        $res = preg_replace("/%7E/", "~", $res);
        return $res;
    }

}

